package com.qqtech.qquan.im.service;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.glassfish.jersey.client.JerseyWebTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.qqtech.core.frame.dao.BaseDao;
import com.qqtech.core.frame.service.BaseServiceImpl;
import com.qqtech.qquan.im.dao.ImGroupDao;
import com.qqtech.qquan.im.dao.ImUserDao;
import com.qqtech.qquan.im.enums.HTTPMethod;
import com.qqtech.qquan.im.enums.ImRetrunEnum;
import com.qqtech.qquan.im.helper.ImSettings;
import com.qqtech.qquan.im.jersey.Credential;
import com.qqtech.qquan.im.jersey.EndPoints;
import com.qqtech.qquan.im.jersey.JerseyUtils;
import com.qqtech.qquan.im.model.ImGroup;
import com.qqtech.qquan.im.model.ImGroupVo;
import com.qqtech.qquan.im.model.ImUserVo;

@Service
public class ImGroupServiceImpl extends BaseServiceImpl<ImGroup>
		implements ImGroupService {
	public static final Logger LOGGER = LoggerFactory.getLogger(ImGroupServiceImpl.class);
	private static final JsonNodeFactory factory = new JsonNodeFactory(false);
	
	@Resource
	private ImGroupDao imGroupDao;
	@Resource
	private ImUserDao imUserDao;
	@Resource
    private ImSettings imSettings;
	@Resource
	private Credential credential;

	@Override
	protected BaseDao<ImGroup> getBaseDao() {
		return imGroupDao;
	}

	@Override
	public Integer addImGroup(int groupId, String groupName, int maxusers, int ownerId) {
		if(imGroupDao.getByGroupId(groupId)!=null){//群组groupId已添加			
			return 0;
		}
		String imOwnerId= transUserID2ImID(ownerId);
		if(imOwnerId==null){
			return 0;
		}		
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId!=null){			
			LOGGER.info("group id: " + groupId+" info: 已注册过");
			return 0;
		}
		ObjectNode dataObjectNode = JsonNodeFactory.instance.objectNode();
		dataObjectNode.put("groupname", groupName);
		dataObjectNode.put("desc", groupName);
		dataObjectNode.put("approval", false);//加入公开群是否需要批准，默认值是false
		dataObjectNode.put("public", true);//是否公开群
		dataObjectNode.put("maxusers", maxusers);
		dataObjectNode.put("owner", imOwnerId);
		ArrayNode arrayNode = JsonNodeFactory.instance.arrayNode();
		dataObjectNode.set("members", arrayNode);
		ObjectNode returnObj = creatGroup4HuanXin(dataObjectNode);		
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){
			imGroupId=returnObj.get("data").path("groupid").asText();
			ImGroup newImGroup = new ImGroup();
			newImGroup.setGroupId(groupId);
			newImGroup.setImGroupId(imGroupId);
			newImGroup.setName(groupName);
			return imGroupDao.insert(newImGroup);//存放在本地数据库
			
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    }
		return 0;
	}

	@Override
	public Integer deleteGroup(int groupId) {
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId==null){			
			return ImRetrunEnum.FAIL.getCode();
		}
		ObjectNode returnObj =  deleteGroup4HuanXin(imGroupId) ;
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){
			boolean success=returnObj.get("data").path("success").asBoolean();
			if(success){
				ImGroup imGroup = new ImGroup();
				imGroup.setGroupId(groupId);
				imGroup.setImGroupId(imGroupId);
				imGroupDao.delete(imGroup);
				return ImRetrunEnum.SUCESS.getCode();
			}else{
				return ImRetrunEnum.FAIL.getCode();
			}
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    	return ImRetrunEnum.FAIL.getCode();
	    }
	}
	
	@Override
	public List<ImUserVo> getImGroupsMembers(int groupId) {
		List<ImUserVo> userList= null;
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId==null){			
			return null;
		}
		
		ObjectNode returnObj = getGroupMembers4HuanXin(imGroupId);
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){
			Iterable<JsonNode> JsonNodeList =returnObj.get("data");
			userList=new ArrayList<ImUserVo>();
			ImUserVo imUser=null;
			for(JsonNode oneMenber: JsonNodeList){				
				if(oneMenber.get("member")!=null){
					imUser=imUserDao.getByImId(oneMenber.get("member").asText());
					userList.add(imUser);
				}else{
					imUser=imUserDao.getByImId(oneMenber.get("owner").asText());
					userList.add(imUser);
				}				
			}
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    }
		return userList;
	}

	@Override
	public Integer deleteGroupMember(int groupId, int memberId) {
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId==null){			
			return ImRetrunEnum.FAIL.getCode();
		}
		
		String imId= transUserID2ImID(memberId);
		if(imId==null){
			return ImRetrunEnum.FAIL.getCode();
		}

		ObjectNode returnObj = deleteGroupMember4HuanXin(imGroupId, imId);
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){			
			boolean result = returnObj.get("data").path("result").asBoolean();
			if(result){
				return ImRetrunEnum.SUCESS.getCode();
			}else{
				return ImRetrunEnum.FAIL.getCode();
			}
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    }
		return ImRetrunEnum.FAIL.getCode();
	}

	@Override
	public Integer addGroupMember(int groupId, int memberId) {
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId==null){			
			return ImRetrunEnum.FAIL.getCode();
		}
		String imId= transUserID2ImID(memberId);
		if(imId==null){
			return ImRetrunEnum.FAIL.getCode();
		}

		ObjectNode returnObj = addGroupMember4HuanXin(imGroupId, imId);
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){
			boolean result = returnObj.get("data").path("result").asBoolean();
			if(result){
				return ImRetrunEnum.SUCESS.getCode();
			}else{
				return ImRetrunEnum.FAIL.getCode();
			}
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    }
		return ImRetrunEnum.FAIL.getCode();
	}

	
	/**
	 * 根据 userId 查询 imid
	 * @param userId
	 * 			圈圈系统用户id
	 * @return imid
	 * 			环信服务用户id (用于单聊)
	 */
	private String transUserID2ImID(int userId){
		ImUserVo imUser = imUserDao.getByUserId(userId);
		if(imUser==null){
			LOGGER.error("wrh用户id:"+userId+" 未注册IM 用户");
			return null;
		}else{
			return imUser.getImId();
		}
	}
	
	/**
	 * 根据 groupId 查询 imGroupId
	 * @param groupId
	 * 			圈子id
	 * @return imGroupId
	 * 			环信服务 群组id (用于群聊)
	 */
	private String transGroupID2ImGroupID(int groupId){
		ImGroupVo imGroup = imGroupDao.getByGroupId(groupId);
		if(imGroup==null){			
			LOGGER.error("group: " + groupId+" error: 未注册");
			return null;			
		}else{
			return imGroup.getImGroupId();
		}
	}
	
	
	/**
	 * 在环信服务器上对应的appKey应用下添加一个群组
	 * @param dataObjectNode
	 * @return
	 */
	private ObjectNode creatGroup4HuanXin(ObjectNode dataObjectNode) {
		/**
		 {
		    "groupname":"testrestgrp12", //群组名称，此属性为必须的
		    "desc":"server create group", //群组描述，此属性为必须的
		    "public":true, //是否是公开群，此属性为必须的
		    "maxusers":300, //群组成员最大数（包括群主），值为数值类型，默认值200，此属性为可选的
		    "approval":true, //加入公开群是否需要批准，默认值是false（加入公开群不需要群主批准），此属性为必选的，私有群必须为true
		    "owner":"jma1", //群组的管理员，此属性为必须的
		    "members":["jma2","jma3"] //群组成员，此属性为可选的，但是如果加了此项，数组元素至少一个（注：群主jma1不需要写入到members里面）
			} 
		 */

		ObjectNode objectNode = factory.objectNode();
		if (!dataObjectNode.has("groupname")) {
			objectNode.put("message", "群组名称(groupname)不能为空.");
			return objectNode;
		}
		if (!dataObjectNode.has("desc")) {
			objectNode.put("message", "群组描述(desc)不能为空.");
			return objectNode;
		}
		if (!dataObjectNode.has("public")) {
			objectNode.put("message", "群组公开属性(public)不能为空.");

			return objectNode;
		}
		if (!dataObjectNode.has("approval")) {
			objectNode.put("message", "群组属性【加入公开群是否需要批准】为空.");
			return objectNode;
		}
		if (!dataObjectNode.has("owner")) {
			objectNode.put("message", "群主为空.");
			return objectNode;
		}
		if (!dataObjectNode.has("members") || !dataObjectNode.path("members").isArray()) {
			objectNode.put("message", "群组属性【成员】为空.");
			return objectNode;
		}

		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.CHATGROUPS_TARGET.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1]);

			objectNode = JerseyUtils.sendRequest(webTarget, dataObjectNode, credential, HTTPMethod.METHOD_POST, null);
			int statusCode =objectNode.get("statusCode").asInt();//200成功，401验证失败
		    if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, dataObjectNode, credential, HTTPMethod.METHOD_POST, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectNode;
	}
	

	/**
	 * 在环信服务器上对应的appKey应用下删除一个群组
	 * @param chatgroupid
	 * @return
	 */
	private ObjectNode deleteGroup4HuanXin(String chatgroupid) {
		ObjectNode objectNode = factory.objectNode();

		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.CHATGROUPS_TARGET.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1]).path(chatgroupid);

			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_DELETE, null);
			int statusCode =objectNode.get("statusCode").asInt();//200成功，401验证失败
		    if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_DELETE, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectNode;
	}
	
	/**
	 * 在环信服务器上对应的appKey应用下查询一个群组的成员
	 * @param chatgroupid
	 * @return
	 */
	private ObjectNode getGroupMembers4HuanXin(String chatgroupid) {

		ObjectNode objectNode = factory.objectNode();

		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.CHATGROUPS_TARGET.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1]).path(chatgroupid).path("users");

			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
			int statusCode =objectNode.get("statusCode").asInt();//200成功，401验证失败
		    if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_GET, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectNode;
	}
	
	/**
	 * 在环信服务器上对应的appKey应用下添加一个成员到指定群组
	 * @param chatgroupid
	 * @param userName
	 * @return
	 */
	private ObjectNode addGroupMember4HuanXin(String chatgroupid, String userName) {

		ObjectNode objectNode = factory.objectNode();

		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.CHATGROUPS_TARGET.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1]).path(chatgroupid).path("users")
					.path(userName);

			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_POST, null);
			int statusCode =objectNode.get("statusCode").asInt();//200成功，401验证失败
		    if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_POST, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectNode;
	}
	/**
	 * 在环信服务器上对应的appKey应用下删除一个群组成员
	 * @param chatgroupid
	 * @param userName
	 * @return
	 */
	private ObjectNode deleteGroupMember4HuanXin(String chatgroupid, String userName) {
		ObjectNode objectNode = factory.objectNode();

		try {
			String APPKEY = imSettings.getAppKey();
			JerseyWebTarget webTarget = EndPoints.CHATGROUPS_TARGET.resolveTemplate("org_name", APPKEY.split("#")[0])
					.resolveTemplate("app_name", APPKEY.split("#")[1]).path(chatgroupid).path("users")
					.path(userName);

			objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_DELETE, null);
			int statusCode =objectNode.get("statusCode").asInt();//200成功，401验证失败
		    if(statusCode==HttpStatus.SC_UNAUTHORIZED){//401验证失败
		    	credential.getNewToken();//重新获取一个token
		    	objectNode = JerseyUtils.sendRequest(webTarget, null, credential, HTTPMethod.METHOD_DELETE, null);
		    }

		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectNode;
	}

	@Override
	public ImGroupVo getByGroupId(Integer groupId) {
		return imGroupDao.getByGroupId(groupId);
	}

	@Override
	public ImGroupVo getByImGroupId(String imGroupId) {
		return imGroupDao.getByImGroupId(imGroupId);
	}

	@Override
	public Integer addImGroupAndMember(int groupId, String groupName,
			int maxusers, int ownerId, List<Integer> members) {
		if(imGroupDao.getByGroupId(groupId)!=null){//群组groupId已添加			
			return 0;
		}
		String imOwnerId= transUserID2ImID(ownerId);
		if(imOwnerId==null){
			return 0;
		}		
		String imGroupId= transGroupID2ImGroupID(groupId);
		if(imGroupId!=null){			
			LOGGER.info("group id: " + groupId+" info: 已注册过");
			return 0;
		}
		ObjectNode dataObjectNode = JsonNodeFactory.instance.objectNode();
		dataObjectNode.put("groupname", groupName);
		dataObjectNode.put("desc", groupName);
		dataObjectNode.put("approval", false);//加入公开群是否需要批准，默认值是false
		dataObjectNode.put("public", true);//是否公开群
		dataObjectNode.put("maxusers", maxusers);
		dataObjectNode.put("owner", imOwnerId);
		ArrayNode arrayNode = JsonNodeFactory.instance.arrayNode();
		String oneMemberIdString = null;
		for(Integer memberId : members){
			oneMemberIdString = transUserID2ImID(memberId);
			arrayNode.add(oneMemberIdString);//添加成员
		}
		dataObjectNode.set("members", arrayNode);
		ObjectNode returnObj = creatGroup4HuanXin(dataObjectNode);		
		int statuscode=returnObj.get("statusCode").asInt();
		if(statuscode==HttpStatus.SC_OK){
			imGroupId=returnObj.get("data").path("groupid").asText();
			ImGroup newImGroup = new ImGroup();
			newImGroup.setGroupId(groupId);
			newImGroup.setImGroupId(imGroupId);
			newImGroup.setName(groupName);
			return imGroupDao.insert(newImGroup);//存放在本地数据库
			
	    }else{
	    	LOGGER.error("返回信息：statuscode: "+statuscode+",error_description: "+returnObj.get("error_description").asText());
	    }
		return 0;
	}

	
}